package com.haoze.nurse.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.haoze.nurse.dao.PatientInHospitalMapper;
import com.haoze.nurse.utils.ExportExcelUtil;
import com.haoze.nurse.vo.InOrOutHispotal;
import org.apache.kafka.common.utils.CopyOnWriteMap;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.haoze.common.enumeration.ConstantEnum;
import com.haoze.common.enumeration.ConstantEnum;
import com.haoze.common.response.Result;
import com.haoze.common.response.ResultGenerator;
import com.haoze.common.utils.DateUtil;
import com.haoze.common.utils.HttpClientUtil;
import com.haoze.common.utils.UUIDUtil;
import com.haoze.nurse.dao.NursePatientMapper;
import com.haoze.nurse.dao.PaymentNoticeMapper;
import com.haoze.nurse.enumeration.ChargeTypeEnum;
import com.haoze.nurse.enumeration.NurseEnum;
import com.haoze.nurse.model.PaymentNoticeEntity;
import com.haoze.nurse.service.QueryStatisticsService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import reactor.util.function.Tuple2;
import reactor.util.function.Tuples;
import tk.mybatis.mapper.entity.Condition;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @Author: Chenchao
 * @CreateTime: 2020-12-11 14:12
 */
@Service
public class QueryStatisticsServiceImpl implements QueryStatisticsService {
    private static final Logger logger = LoggerFactory.getLogger(QueryStatisticsServiceImpl.class);

    @Autowired
    private PaymentNoticeMapper paymentNoticeMapper;
    @Autowired
    private NursePatientMapper nursePatientMapper;
    @Autowired
    private PatientInHospitalMapper patientInHospitalMapper;
    @Value("${his.url.cost}")
    private String cost;
    @Value("${his.url.operationUrl}")
    private String operationUrl;

    @Value("${his.url.circulation}")
    private String circulationUrl;

    @Override
    public List<PaymentNoticeEntity> paymentNoticeConfig(String wardId) throws Exception {
        // 获取his的费用警戒值
        final JSONArray hisPaymentNoticeConfig = getHisPaymentNoticeConfig(wardId);
        Condition condition = new Condition(PaymentNoticeEntity.class);
        condition.createCriteria().andEqualTo("wardId", wardId).andEqualTo("delFlag", NurseEnum.STOP_FLAG_ZERO.getIndex());
        // 查出PaymentNotice表的设置
        final List<PaymentNoticeEntity> paymentNoticeEntities = paymentNoticeMapper.selectByCondition(condition);
        // 如果设置与his不一样更新PaymentNotice表的设置
        handleHisAndNursePaymentNotice(hisPaymentNoticeConfig, paymentNoticeEntities, wardId);
        return paymentNoticeEntities.stream().filter(paymentNoticeEntity ->
                NurseEnum.STOP_FLAG_ZERO.getIndex().equals(paymentNoticeEntity.getDelFlag()))
                .collect(Collectors.toList());
    }

    /**
     * 处理His和Nurse的PaymentNotice
     * 如果设置与his不一样更新PaymentNotice表的设置
     * @param hisPaymentNoticeConfig his的PaymentNotice
     * @param paymentNoticeEntities nurse的PaymentNotice
     * @param wardId
     */
    private void handleHisAndNursePaymentNotice(JSONArray hisPaymentNoticeConfig, List<PaymentNoticeEntity> paymentNoticeEntities, String wardId) {
        if (null == hisPaymentNoticeConfig) {
            // his没有数据，删除nurse对应数据
            paymentNoticeEntities.forEach(paymentNoticeEntity -> {
                paymentNoticeEntity.setDelFlag(NurseEnum.STOP_FLAG_ONE.getIndex());
                paymentNoticeMapper.updateByPrimaryKey(paymentNoticeEntity);
            });
            paymentNoticeEntities.clear();
            return;
        }
        // 过滤掉非医保和自费
        List<JSONObject> hisPaymentNoticeConfigList = JSONObject.parseArray(hisPaymentNoticeConfig.toJSONString(), JSONObject.class);
        hisPaymentNoticeConfigList = hisPaymentNoticeConfigList.stream().filter(config ->
                ChargeTypeEnum.MEDICAL_INSURANCE.matches((String) config.get("charge_type"))
                        || ChargeTypeEnum.PAY_SELF.matches((String) config.get("charge_type"))).collect(Collectors.toList());
        // 删除hisPaymentNoticeConfigList没有的charge_type
        for (PaymentNoticeEntity paymentNoticeEntity : paymentNoticeEntities) {
            final long count = hisPaymentNoticeConfigList.stream().filter(config ->
                    paymentNoticeEntity.getChargeType().equals(config.getString("charge_type"))).count();
            if (count <= 0) {
                paymentNoticeEntity.setDelFlag(NurseEnum.STOP_FLAG_ONE.getIndex());
                paymentNoticeMapper.updateByPrimaryKey(paymentNoticeEntity);
            }
        }
        // 比较hisPaymentNoticeConfigList和paymentNoticeEntities
        for (JSONObject config : hisPaymentNoticeConfigList) {
            // 找出paymentNoticeEntities中对应charge_type，有就更新与his一致，没有就新加一条
            boolean requireInsert = true;
            for (PaymentNoticeEntity entity : paymentNoticeEntities) {
                if (entity.getChargeType().equals(config.getString("charge_type"))
                        && NurseEnum.STOP_FLAG_ZERO.getIndex().equals(entity.getDelFlag())) {
                    requireInsert = false;
                    // 更新
                    entity.initUpdate();
                    paymentNoticeMapper.updateByPrimaryKey(copyPaymentNoticeProperties(config, entity, wardId));
                }
            }
            logger.info("handleHisAndNursePaymentNotice requireInsert:{}", requireInsert);
            if (requireInsert) {
                // 新增
                final PaymentNoticeEntity entity = new PaymentNoticeEntity();
                entity.setPaymentNoticeId(UUIDUtil.randomString());
                entity.initAdd();
                final int insert = paymentNoticeMapper.insert(copyPaymentNoticeProperties(config, entity, wardId));
                if (insert > 0) {
                    paymentNoticeEntities.add(entity);
                }
            }
        }
    }

    /**
     * 将his中获取的属性拷入nurse
     * @param config
     * @param entity
     * @param wardId
     * @return
     */
    private PaymentNoticeEntity copyPaymentNoticeProperties(JSONObject config, PaymentNoticeEntity entity, String wardId) {
        entity.setDelFlag(NurseEnum.STOP_FLAG_ZERO.getIndex());
        entity.setChargeType(config.getString("charge_type"));
        entity.setPrimaryId(config.getString("primary_id"));
        entity.setWardId(wardId);
        entity.setMedicineQuota(config.getBigDecimal("extend_pharmacy") == null ? new BigDecimal(0) : config.getBigDecimal("extend_pharmacy"));
        entity.setDunningAmount(config.getBigDecimal("press_money") == null ? new BigDecimal(0) : config.getBigDecimal("press_money"));
        entity.setSponsorMedicine(config.getBigDecimal("assure_money") == null ? new BigDecimal(0) : config.getBigDecimal("assure_money"));
        return entity;
    }

    /**
     * 获取his的费用警戒设置
     *
     * 例： http request body {"operationID":"10034","c_request":{"request":{"ward_code":"H2127","operator":"1303","operationdate":"2021-02-25 11:22:00"}}}
     * http response body {"Error_Msg":"成功","Error_Id":"1","c_response":{"response":{"error_msg":"成功","error_id":1,"logid":1866103,"list":[{"charge_type":"农保","alert":"","primary_id":"H2127-农保","extend_pharmacy":-2000},{"charge_type":"医保","alert":"","primary_id":"H2127-医保","extend_pharmacy":-2000},{"charge_type":"自费","alert":"","primary_id":"H2127-自费","extend_pharmacy":-2000}]}}}
     * @param wardId 病区号
     * @return response body的JSONObject对象
     */
    private JSONArray getHisPaymentNoticeConfig(String wardId) throws Exception {
        String userId = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()
                .getHeader("zuul_id");
        logger.info("getHisPaymentNoticeConfig userId:{}", userId);
        String personCode = nursePatientMapper.queryPersonCodeByUserId(userId);
        String deptCode = nursePatientMapper.queryDeptCodeByDeptId(wardId);
        final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        final String format = formatter.format(LocalDateTime.now());
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> request = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        param.put("operator", personCode); // 操作人-工号
        param.put("operationdate", format); // 操作时间yyyy-mm-dd hh:mm:ss
        param.put("ward_code", deptCode); // 病区编码
        request.put("request", param);
        map.put("operationID", ConstantEnum.HIS_PAYMENT_NOTICE_10034.getKey()); // 操作ID(his根据id码执行对应操作)
        map.put("c_request", request);
        logger.info("getHisPaymentNoticeConfig request body:{}", map);
        final JSONObject jsonObject = HttpClientUtil.sendPost(operationUrl, map);
        logger.info("getHisPaymentNoticeConfig response body:{}", jsonObject);
        final JSONObject cResponse = (JSONObject) jsonObject.get("c_response");
        final JSONObject response = (JSONObject) cResponse.get("response");
        final Integer errorId = (Integer) response.get("error_id");
        final JSONArray list = (JSONArray) response.get("list");
        logger.info("getHisPaymentNoticeConfig response errorId:{}", errorId);
        if (1 != errorId) {
            // 响应失败
            throw new Exception("his费用警戒值查询失败");
        }
        return list;
    }

    @Override
    public Result savePaymentNotice(PaymentNoticeEntity paymentNotice) {
        String oprType = "C"; // 操作类型：C新增/U更新/D删除
        if (StringUtils.isBlank(paymentNotice.getPaymentNoticeId())) {
            PaymentNoticeEntity temp = new PaymentNoticeEntity();
            temp.setDelFlag(NurseEnum.STOP_FLAG_ZERO.getIndex());
            temp.setWardId(paymentNotice.getWardId());
            temp.setChargeType(paymentNotice.getChargeType());
            int cnt = paymentNoticeMapper.selectCount(temp);
            if (cnt > 0) {
                return ResultGenerator.genFailedResult("该病区已存在当前设置，请勿重复添加。");
            }
            paymentNotice.setPaymentNoticeId(UUIDUtil.randomString());
            paymentNotice.setDelFlag(NurseEnum.STOP_FLAG_ZERO.getIndex());
            paymentNotice.initAdd();
            paymentNoticeMapper.insert(paymentNotice);
        } else {
            oprType = "U";
            paymentNotice.initUpdate();
            paymentNoticeMapper.updateByPrimaryKeySelective(paymentNotice);
        }
        updateToHis(paymentNotice, oprType);
        logger.info("savePaymentNotice oprType:{},paymentNoticeId:{}", oprType, paymentNotice.getPaymentNoticeId());
        return ResultGenerator.genOkResult();
    }

    /**
     * 同步数据到his
     * @param paymentNotice
     * @param oprType 操作类型：C新增/U更新/D删除
     */
    private void updateToHis(PaymentNoticeEntity paymentNotice, String oprType) {
        final String wardId = paymentNotice.getWardId();
        String userId = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest()
                .getHeader("zuul_id");
        logger.info("updateToHis userId:{}", userId);
        String personCode = nursePatientMapper.queryPersonCodeByUserId(userId);
        String deptCode = nursePatientMapper.queryDeptCodeByDeptId(wardId);
        final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        final String format = formatter.format(LocalDateTime.now());
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> request = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        Map<String, Object> param_2 = new HashMap<>();
        param_2.put("opr_type", oprType);
        param_2.put("primary_id", paymentNotice.getPrimaryId());
        param_2.put("charge_type", paymentNotice.getChargeType());
        param_2.put("extend_pharmacy", paymentNotice.getMedicineQuota());
        param_2.put("press_money", paymentNotice.getDunningAmount());
        param_2.put("assure_money", paymentNotice.getSponsorMedicine());
        param_2.put("alert", "");
        final ArrayList<Map<String, Object>> list = new ArrayList<>();
        list.add(param_2);
        param.put("operator", personCode);
        param.put("operationdate", format);
        param.put("ward_code", deptCode);
        param.put("list", list);
        request.put("request", param);
        map.put("operationID", ConstantEnum.HIS_PAYMENT_NOTICE_10033.getKey());
        map.put("c_request", request);
        logger.info("updateToHis request body:{}", map);
        final JSONObject jsonObject = HttpClientUtil.sendPost(operationUrl, map);
        logger.info("updateToHis response body:{}", jsonObject);
    }

    @Override
    public Result delPaymentNotice(String id) {
        String oprType = "D";
        PaymentNoticeEntity paymentNotice = paymentNoticeMapper.selectByPrimaryKey(id);
        logger.info("delPaymentNotice paymentNotice:{}", paymentNotice);
        if (paymentNotice != null) {
            paymentNotice.setDelFlag(NurseEnum.STOP_FLAG_ONE.getIndex());
            paymentNotice.initUpdate();
            paymentNoticeMapper.updateByPrimaryKeySelective(paymentNotice);
        }
        updateToHis(paymentNotice, oprType);
        return ResultGenerator.genOkResult();
    }

    @Override
    public Result queryPatientPaymentNotice(String wardId, String queryString) {
        List<Map<String, String>> patientList;
        String inpatNumSearch = "";
        String userName = "";
        if (queryString != null && queryString.length() > 0) {
            boolean isInt = Pattern.compile("^[0-9]").matcher(queryString.substring(0, 1)).find();
            if (isInt) {
                inpatNumSearch = queryString;
            } else {
                userName = queryString;
            }
        }
        patientList = nursePatientMapper.getPatientsInHospitalBySearch(wardId, inpatNumSearch, userName);
        List<CompletableFuture<Tuple2<String, JSONObject>>> futures = patientList.parallelStream().map(pat -> CompletableFuture.supplyAsync(() -> {
            String patientId = pat.get("medicalNum");
            Map<String, Object> param = new HashMap<>();
            param.put("as_patientId", patientId);
            param.put("operationID", "10001");
            param.put("al_visitId", "1");
            param.put("al_doctor_type", "");
            JSONObject jsonObject = HttpClientUtil.sendPost(cost, param);
            if (jsonObject.getString("data") != null) {
                JSONObject cost = JSONArray.parseArray(jsonObject.getString("data"), JSONObject.class).get(0);
                return Tuples.of(patientId, cost);
            } else {
                return null;
            }
        })).collect(Collectors.toList());
        Map<String, JSONObject> patMap = new HashMap<>();
        try {
            CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenApply(v -> futures.stream().map(CompletableFuture::join)
                    .collect(Collectors.toList())).get().stream().filter(Objects::nonNull).forEach(tuple2 -> patMap.put(tuple2.getT1(), tuple2.getT2()));
        } catch (Exception e) {
            logger.error("调用第三方接口报错", e);
        }
        Condition condition = new Condition(PaymentNoticeEntity.class);
        condition.createCriteria().andEqualTo("wardId", wardId).andEqualTo("delFlag", NurseEnum.STOP_FLAG_ZERO.getIndex());
        List<PaymentNoticeEntity> paymentNoticeList = paymentNoticeMapper.selectByCondition(condition);
        handlePaymentNotice(paymentNoticeList);
        patientList.stream().forEach(map -> {
            map.putIfAbsent("confirmAmt","0");
            JSONObject jsonObject = patMap.get(map.get("medicalNum"));
            if (jsonObject == null) {
                jsonObject = new JSONObject();
            }
            if (jsonObject.get("CHARGE_TYPE") == null) {
                map.put("chargeType", "自费");
            } else if (jsonObject.getString("CHARGE_TYPE").contains("自费")) {
                map.put("chargeType", "自费");
            } else {
                map.put("chargeType", jsonObject.getString("CHARGE_TYPE"));
            }
//            map.put("classFlag", StringUtils.isBlank(jsonObject.getString("CLASS_FLAG")) ? "0" : jsonObject.getString("CLASS_FLAG"));//1留观病人;0非留观病人
//            map.put("specialFlag", StringUtils.isBlank(jsonObject.getString("SPECIAL_FLAG")) ? "0" : jsonObject.getString("SPECIAL_FLAG"));//1绿色通道病人；0非绿色通道病人
            map.put("totalCostSettle", new BigDecimal(StringUtils.isBlank(jsonObject.getString("TOTAL_COST_SETTLE")) ? "0" : jsonObject.getString("TOTAL_COST_SETTLE")).toString());//已结
            map.put("totalCost", new BigDecimal(StringUtils.isBlank(jsonObject.getString("TOTAL_COST")) ? "0" : jsonObject.getString("TOTAL_COST")).toString());//未结
            map.put("guarantorAmt", new BigDecimal(StringUtils.isBlank(jsonObject.getString("GUARANTOR_AMT")) ? "0" : jsonObject.getString("GUARANTOR_AMT")).toString());
            BigDecimal yeJe = new BigDecimal(StringUtils.isBlank(jsonObject.getString("YE_JE")) ? "0" : jsonObject.getString("YE_JE"));
            map.put("yeJe", yeJe.toString());//余额
            map.put("yjjAmt", new BigDecimal(StringUtils.isBlank(jsonObject.getString("YJJ_AMT")) ? "0" : jsonObject.getString("YJJ_AMT")).toString()); //预交金
            map.put("zlJe", new BigDecimal(StringUtils.isBlank(jsonObject.getString("ZL_JE")) ? "0" : jsonObject.getString("ZL_JE")).toString()); //自理金额
            map.put("totalAmt", new BigDecimal(map.get("totalCostSettle")).add(new BigDecimal(map.get("totalCost"))).toString()); //总费用
            for (PaymentNoticeEntity paymentNotice : paymentNoticeList) {
                if ("自费".equals(paymentNotice.getChargeType()) && "自费".equals(map.get("chargeType"))) {
                    this.compareAmt(map, paymentNotice, jsonObject);
                    break;
                } else if ("医保".equals(paymentNotice.getChargeType()) && !"自费".equals(map.get("chargeType"))) {
                    this.compareAmt(map, paymentNotice, jsonObject);
                    break;
                }
            }
        });
        return ResultGenerator.genOkResult(patientList);
    }
    @Override
    public Result queryPatientInOrOutHospital(Integer status, String wardDeptId, Integer page, Integer pageSize,String startTime, String endTime) {
        PageHelper.startPage(page,pageSize);
        List<InOrOutHispotal> list=null;
        if (status==1){
            list = nursePatientMapper.queryPatientInHospital(status, wardDeptId);
            list.parallelStream().forEach(vo -> {
                if (vo.getInpatNum()!=null){
                    Map<String, Object> patinfo = this.getPatinfo( vo.getInpatNum());
                    vo.setChargetype((String) patinfo.get("charge_type"));
                    vo.setYllb((String) patinfo.get("yllb"));
                }else{
                    vo.setChargetype(null);
                    vo.setYllb(null);
                }
            });
        }else{
           list=nursePatientMapper.queryPatientOutHospital(status,wardDeptId, startTime,endTime);
        }
        list.parallelStream().forEach(inOrOutHispotal -> inOrOutHispotal.setMedicalNum(inOrOutHispotal.getInpatNum().split("-")[0]));
        PageInfo pageInfo = new PageInfo(list);
        return ResultGenerator.genOkResult(pageInfo);
    }

    public Map<String,Object> getPatinfo(String inpatNum) {
        Map<String, Object> patinfo = new CopyOnWriteMap<>();
        String userId = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getHeader("zuul_id");
        //userId="bf533ba10ec64ab0bbf360c44fa7a787";
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> requestMap = new HashMap<>();
        Map<String, Object> param = new HashMap<>();
        param.put("patient_id", inpatNum.split("-")[0]);
        param.put("visit_id", Integer.parseInt(inpatNum.split("-")[1]));
        param.put("operator", patientInHospitalMapper.queryPersonCodeByUserId(userId));
        param.put("operationdate", DateUtil.dateToString(new Date(), "yyyy-MM-dd HH:mm:ss"));

        requestMap.put("request", param);
        map.put("c_request", requestMap);
        map.put("operationID", ConstantEnum.HIS_CIRCULATION_10013.getKey());
        System.out.println(JSON.toJSONString(map));
        JSONObject jsonObject = HttpClientUtil.sendPost(circulationUrl, map);
        if (null != jsonObject) {
            Integer resInt = Integer.valueOf((String) jsonObject.get("Error_Id"));
            if (resInt > 0) {
                if (jsonObject.getString("c_response") != null) {
                    Map<String, Object> cresponseMap = JSON.parseObject(jsonObject.getString("c_response"), new TypeReference<Map<String, Object>>() {
                    });
                    Map<String, Object> response = (Map<String, Object>) cresponseMap.get("response");
                    if (response != null && response.get("patinfo") != null) {
                        patinfo = (Map<String, Object>) response.get("patinfo");
                    }
                }
            }
        }
        return patinfo;
    }

    @Override
    public void exportPatientInOrOutHospital(Integer status,List list, HttpServletRequest req, HttpServletResponse res) {
        if(list!=null && list.size()>0){
            String [] title = null;        //设置表格表头字段
            String [] properties = null;  // 查询对应的字段
            ExportExcelUtil excelExport2 = new ExportExcelUtil();
            if (status==1){
                title=new String[]{"床号","等级","姓名","性别","出身年月","职业","结账方式","医疗类别","住院号","入院日期","床位医师","护理","入住科室","入住日期","通讯地址","联系人","电话"};
                properties=new String[]{"bedLabel","bedGrade","patName","sex","birthday","occupation","chargetype","yllb","inpatNum","inDateTime","userName","rank","deptName","inWardDateTiem","contactsTownship","contactsName","contactsPhoneNum"};
                excelExport2.setSheetName("在院病人信息");
                excelExport2.setTitle("在院病人信息");
            }else{
                title=new String[]{"住院号","病人ID","姓名","性别","年龄","职业","入院日期","手术日期","出院日期","床号","住院天数","切口愈合","出院方式","出院主诊断","手术名称","床位医师","手术医师","主治医师","通讯地址","联系人","电话","本人电话"};
                properties=new String[]{"inpatNum","patdataId","patName","sex","birthday","occupation","inDateTime","operDate","outDateTime","bedLabel","day","cut","outHospitalType","diagName","operName","userName","personName","userName","contactsTownship","contactsName","contactsPhoneNum","ownPhoneNum"};
                excelExport2.setSheetName("出院病人信息");
                excelExport2.setTitle("出院病人信息");
            }

            excelExport2.setData(list);
            excelExport2.setHeardKey(properties);
            excelExport2.setFontSize(14);
            excelExport2.setSheetName("在出院病人信息");
            excelExport2.setTitle("在出院病人信息");
            excelExport2.setHeardList(title);
            try {
                excelExport2.exportExport(req, res);
            } catch (Exception e) {
                logger.error(e.getMessage());
            }
        }
    }

    /**
     * 对费用警戒列表加工处理，添加默认值
     * 保证后续没有设置警戒病区，余额<0时有提示
     * @param paymentNoticeList 费用警戒列表
     */
    private void handlePaymentNotice(List<PaymentNoticeEntity> paymentNoticeList) {
        if (null != paymentNoticeList && paymentNoticeList.size() >= 2) {
            // 包含自费和医保两个警戒点
            return;
        }
        if (CollectionUtils.isEmpty(paymentNoticeList)) {
            // 为空加入自费和医保两个默认对象
            if (null == paymentNoticeList) {
                paymentNoticeList = new ArrayList<>();
            }
            paymentNoticeList.add(genPaymentNoticeEntity("自费"));
            paymentNoticeList.add(genPaymentNoticeEntity("医保"));
            return;
        }
        PaymentNoticeEntity paymentNoticeEntity = paymentNoticeList.get(0);
        if ("自费".equals(paymentNoticeEntity.getChargeType())) {
            // 只有自费，加入默认医保
            paymentNoticeList.add(genPaymentNoticeEntity("医保"));
            return;
        }
        paymentNoticeList.add(genPaymentNoticeEntity("自费"));
        // 只有医保，加入默认自费
    }

    private PaymentNoticeEntity genPaymentNoticeEntity(String chargeType) {
        PaymentNoticeEntity paymentNoticeEntity = new PaymentNoticeEntity();
        paymentNoticeEntity.setChargeType(chargeType);
        paymentNoticeEntity.setDunningAmount(new BigDecimal(-0.00001));
        paymentNoticeEntity.setMedicineQuota(new BigDecimal(-0.00001));
        return paymentNoticeEntity;
    }

    private void compareAmt(Map<String, String> map, PaymentNoticeEntity paymentNotice, JSONObject jsonObject) {
        if (paymentNotice.getMedicineQuota() != null && new BigDecimal(map.get("yeJe")).compareTo(paymentNotice.getMedicineQuota()) < 0) {
            map.put("medicineQuotaFlag", "1");
        } else {
            map.put("medicineQuotaFlag", "0");
        }
        if (paymentNotice.getDunningAmount() != null && new BigDecimal(map.get("yeJe")).compareTo(paymentNotice.getDunningAmount()) < 0) {
            map.put("dunningAmountFlag", "1");
        } else {
            map.put("dunningAmountFlag", "0");
        }
        String guarantor_amt = jsonObject.getString("GUARANTOR_AMT");
        if (StringUtils.isNotBlank(guarantor_amt) && paymentNotice.getSponsorMedicine() == null) {
            BigDecimal guarantorAmt = new BigDecimal(guarantor_amt);
            if (guarantorAmt.compareTo(new BigDecimal(0)) > 0) {
                guarantorAmt = guarantorAmt.multiply(new BigDecimal(-1));
            }
//            if (new BigDecimal(map.get("yeJe")).compareTo(guarantorAmt) <= 0) {
//                map.put("sponsorMedicineFlag", "1");
//            } else {
//                map.put("sponsorMedicineFlag", "0");
//            }
            //担保金额大于发药金额 以担保为主 担保金额如果是正数，换成负数处理，判断变为小于
            if (guarantorAmt.compareTo(paymentNotice.getMedicineQuota()) < 0) {
                if (new BigDecimal(map.get("yeJe")).compareTo(new BigDecimal(guarantor_amt)) < 0) {
                    map.put("medicineQuotaFlag", "1");
                } else {
                    map.put("medicineQuotaFlag", "0");
                }
            }
        } else if (StringUtils.isBlank(guarantor_amt) && paymentNotice.getSponsorMedicine() != null) {
//            if (new BigDecimal(map.get("yeJe")).compareTo(paymentNotice.getSponsorMedicine()) <= 0) {
//                map.put("sponsorMedicineFlag", "1");
//            } else {
//                map.put("sponsorMedicineFlag", "0");
//            }
            //担保金额大于发药金额 以担保为主 担保金额如果是正数，换成负数处理，判断变为小于
            if (paymentNotice.getDunningAmount().compareTo(paymentNotice.getMedicineQuota()) <= 0) {
                if (new BigDecimal(map.get("yeJe")).compareTo(paymentNotice.getDunningAmount()) < 0) {
                    map.put("medicineQuotaFlag", "1");
                } else {
                    map.put("medicineQuotaFlag", "0");
                }
            }
        } else if (StringUtils.isNotBlank(guarantor_amt) && paymentNotice.getSponsorMedicine() != null) {
            BigDecimal guarantorAmt = new BigDecimal(guarantor_amt);
            if (guarantorAmt.compareTo(new BigDecimal(0)) > 0) {
                guarantorAmt = guarantorAmt.multiply(new BigDecimal(-1));
            }
            BigDecimal amt = guarantorAmt.min(paymentNotice.getSponsorMedicine());
            if (new BigDecimal(map.get("yeJe")).compareTo(amt) < 0) {
                map.put("sponsorMedicineFlag", "1");
            } else {
                map.put("sponsorMedicineFlag", "0");
            }
            //担保金额大于发药金额 以担保为主 担保金额如果是正数，换成负数处理，判断变为小于
            if (amt.compareTo(paymentNotice.getMedicineQuota()) <= 0) {
                if (new BigDecimal(map.get("yeJe")).compareTo(paymentNotice.getDunningAmount()) < 0) {
                    map.put("medicineQuotaFlag", "1");
                } else {
                    map.put("medicineQuotaFlag", "0");
                }
            }
        } else {
            map.put("sponsorMedicineFlag", "0");
        }
    }
}
